{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Speeding Up Quantum Circuit Simulation by MBQC\n",
    "\n",
    "<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Introduction\n",
    "\n",
    "Quantum computation utilizes the peculiar laws in the quantum world and provides us with a novel and promising way of information processing. Nowadays, quantum computer is still in its early stage of development, with prohibitive manufacture, operating and maintenance costs. Fortunately, simulating quantum algorithms with classical computers is satisfactory to most scientific research and education. In 2012, John Preskill proposed the concept of \"quantum advantages\" (also known as \"quantum supremacy\"), starting a big competition between the performance of quantum and classical computers [1,2]. As different research teams announcing the achievements of quantum supremacy of their devices, there is also an increasing amount of people focusing on how to challenge the 'quantum supremacy' of those quantum computing devices, by designing efficient simulation algorithms in classical computers. How to improve the capability of simulating quantum algorithms classically is one of the most important topics in the field.\n",
    "\n",
    "When simulating quantum algorithms on classical computers, we usually use column vectors to represent and store a quantum state. However, to store the information of a single qubit quantum state, we need a column vector of size $2 \\times 1$, while for an $n$-qubit quantum state, we need a column vector with the size as large as $2^{n} \\times 1$. Therefore, using column vectors to store a quantum state rapidly consumes memory and computational resources, as its size increases exponentially to the number of qubits. To break through this bottleneck, one approach is to replace the data structure of qubit's information storage. The commonly used data structures to replace column vectors include decision diagrams, tensor networks (including matrix product states), etc. Each data structure has its distinctive way of quantum circuit simulation. However, all these stay in the framework of **Quantum Circuit Model**.\n",
    "\n",
    "Another idea to solve the bottleneck of computation resources is to jump out of the framework of the quantum circuit model and simulate a circuit by its equivalents. **Measurement-Based Quantum Computation (MBQC)** [3-6] is another universal quantum computation model, that receives wide attention by its unique way of performing computation since its proposal. As is mentioned in [MBQC Quick Start Guide](MBQC_EN.ipynb), for non-adaptive measurements, not only can they be carried out simultaneously in physical implementation, but in classical simulation, they can also help to reduce the effective number of qubits in the computation, thus reducing the consumption of memory and computational resources. \n",
    "\n",
    "In this tutorial, we will introduce a new scheme of quantum circuit simulation by firstly translating it into its MBQC equivalent and then optimizing the order of measurements to finally improve the simulation efficiency. In the meanwhile, we will also demonstrate applications of the ``circuit`` and ``mcalculus`` modules in our MBQC package by two concrete examples. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quantum Circuit Simulation\n",
    "\n",
    "Our new scheme of quantum circuit simulation contains three steps, and each step corresponds to a module in the MBQC package. The main class in each module and their functionalities are shown in Table 1.\n",
    "\n",
    "|Step|Module|Class|Functionality|\n",
    "|:---:|:---:|:---:|:---:|\n",
    "|Quantum circuit construction|``qobject`` module|``Circuit`` class|Construct quantum circuit (with quantum gates and measurements)|\n",
    "|Translation and optimization|``mcalculus`` module|``MCalculus`` class|Translate quantum circuit into MBQC equivalent and optimize it|\n",
    "|Simulation |``simulator`` module|``MBQC`` class|Run measurement pattern and obtain the computation results|\n",
    "\n",
    "<div style=\"text-align:center\">Table 1: Quantum circuit simulation scheme by MBQC proposed in this tutorial </div>\n",
    "\n",
    "Next, we will introduce the above three steps in more details and with code implementations."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Quantum circuit construction\n",
    "\n",
    "In the module ``qobject``, we provide a class `Circuit` to store the information of quantum gates and measurements in the circuit model. We can call the methods in `Circuit` to build our own quantum circuit after instantiation. The syntax to add quantum gates is almost the same as in [UAnsatz](https://qml.baidu.com/api/paddle_quantum.circuit.uansatz.html) which you might be quite familiar with. Please refer to the tutorial [Quantum Neural Network](https://qml.baidu.com/quick-start/quantum-neural-network.html) for more details. Let's take the circuit in Figure 1 as an example to show the usage of ``Circuit``.\n",
    "\n",
    "![Circuit example](./figures/mbqc-fig-pat-cir-intro.png)\n",
    "<div style=\"text-align:center\">Figure 1: A simple example of quantum circuit </div>\n",
    "\n",
    "In the figure $Ry$ stands for a rotation-y gate, the 2-qubits gate is $CNOT$ gate, $|0\\rangle$ is the initial quantum state. The code implementation using ``Circuit`` to construct such a circuit is as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import common modules\n",
    "from numpy import pi, random\n",
    "from paddle import to_tensor\n",
    "\n",
    "# Import circuit module\n",
    "from paddle_quantum.mbqc.qobject import Circuit\n",
    "\n",
    "# Initialize ratation angle theta \n",
    "theta = random.rand(4) * 2 * pi \n",
    "    \n",
    "# Transform 'Numpy array' to 'Tensor' in Paddle\n",
    "theta = to_tensor(theta)\n",
    "\n",
    "# Instantiate a quantum circuit\n",
    "qubit_number = 2\n",
    "cir = Circuit(qubit_number)\n",
    "\n",
    "# Add Ry gate\n",
    "cir.ry(theta[0], 0)\n",
    "cir.ry(theta[1], 1)\n",
    "\n",
    "# Add CNOT gate\n",
    "cir.cnot([0, 1])\n",
    "\n",
    "# Add Ry gate\n",
    "cir.ry(theta[2], 0)\n",
    "cir.ry(theta[3], 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, we add measurements to the circuit.\n",
    "\n",
    "**Note**: The way to add measurements in `Circuit` is different from `UAnsatz`! The former is to call `.measure` method before running the circuit, while the latter is to call `.measure` method after running the circuit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Input measurement information\n",
    "# Measure all qubits by default\n",
    "cir.measure()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, we need to pass the constructed circuit to the translation module ``mcalculus`` for further process."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Translation and optimization\n",
    "\n",
    "The basic notions of translation can be referred to [7,8]. Here we just give a brief introduction on translation, optimization, and their code implementations.\n",
    "\n",
    "We have mentioned the \"EMC\" language of MBQC models in [Introduction to the MBQC framework](MBQC_CN.ipynb). So let's briefly review it here. We refer to the MBQC model translated from a circuit model as the **pattern**, and to the MBQC model translated from a single quantum gate or measurement of an output state as the **subpattern** [7]. The translation process of a quantum circuit is actually the following three steps:`\n",
    "\n",
    "- one-by-one translation: translate each quantum gate and measurement into a subpattern;\n",
    "\n",
    "- standardization: integrate all subpatterns into a standard pattern;\n",
    "\n",
    "- simplification and optimization: simplify and optimize all measurement commands in the standard pattern."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In terms of code implementation, we provide `MCalculus` class for this task. We can call the method `set_circuit` to pass the constructed circuit ``cir`` to `MCalculus`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import mcalculus module\n",
    "from paddle_quantum.mbqc.mcalculus import MCalculus\n",
    "\n",
    "# Instantiate MCalculus class\n",
    "mc = MCalculus()\n",
    "\n",
    "# Pass the circuit to MCalculus\n",
    "mc.set_circuit(cir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### One-by-one translation\n",
    "\n",
    "We first translate each quantum gate into an MBQC subpattern. As introduced in [MBQC Quick Start Guide](MBQC_EN.ipynb), the standard \"three-step\" process of MBQC is equivalent to the \"EMC\" language. As for the implementation of the $R_y$ gate, we can map every step of the \"three-step\" process to the \"EMC\" commands, as shown in Table 2:\n",
    "\n",
    "|\"Three-step\" process|\"EMC\" commands|\n",
    "|:---|:---|\n",
    "|**Graph state preparation** <br/> Prepare the input state on vertex $1$, <br/> and plus states on vertices $2,3,4,5$, <br/> perform CZ operation on adjacent vertices. |**Entanglement commands** <br/> $E_{12}E_{23}E_{34}E_{45}$||\n",
    "|**Single-qubit measurement** <br/>  Measure vertex $1$ in the $XY$ plane with angle $\\frac{\\pi}{2}$ and record the outcome $s_1$; <br/> Measure vertex $2$ in the $XY$ plane with angle $(-1)^{s_1 + 1}\\alpha$ and record the outcome $s_2$. <br/> Measure vertex $3$ in the $XY$ plane with angle $-\\frac{\\pi}{2} + (s_1+s_2)\\pi$ and record the outcome $s_3$. <br/> Measure vertex $4$ in the $XY$ plane with angle $s_2\\pi$ and record the outcome $s_4$. |**Measurement commands** <br/>$M_1M_2M_3M_4$|\n",
    "|**Byproduct correction** <br/> Correct byproducts $X^{s_4}$ and $Z^{s_3}$ on vertex $5$ |**Byproduct correction command** <br/>$X_5Z_5$|\n",
    "\n",
    "<div style=\"text-align:center\">Table 2: Correspondence between the \"Three-step\" process and the \"EMC\" commands for implementing Ry in MBQC</div>\n",
    "\n",
    "We arrange the above commands from left to right and get a command list $[E_{12}E_{23}E_{34}E_{45}M_1M_2M_3M_4X_5Z_5]$. The detailed parameters in the commands are omitted here for simplicity. \n",
    "\n",
    "Similarly, the command list of $CNOT$ gate can be given by \\[$E_{12}E_{23}E_{24}M_1 M_2 X_4 Z_3 Z_4$\\]. A measurement in the circuit model can be simply given by a command list \\[$M_1$\\] as measurements in the circuit model play the same role as $Z$ measurements on the output qubits in MBQC."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As for the code implementation, we provide a private method `__to_subpattern` to translate quantum gates and measurements one by one. (This method records all the one-to-one correspondence between gates and subpatterns. You can also customize this function if needed.) Once all the gates and measurements are translated, the information of all the subpatterns is stored in a list named **wild pattern** which will be used for further processes.\n",
    "\n",
    "![Wild pattern](./figures/mbqc-fig-wild_pat.jpg)\n",
    "<div style=\"text-align:center\">Figure 2: Translate quantum gates and measurements one by one to obtain a wild pattern </div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Standardization\n",
    "\n",
    "Once we have a wild pattern, the next step is to do **standardization**, that is, to reorder commands in the wild pattern such that all entanglement commands move to the left, and all the byproduct correction commands move to the right. The resulting pattern is called a **standard pattern**.\n",
    "\n",
    "**Note**: The command list reordering is non-trivial and follows a specific set of rules in [7].\n",
    "\n",
    "![Standard pattern](./figures/mbqc-fig-pat_std.jpg)\n",
    "<div style=\"text-align:center\">Figure 3: Transform a wild pattern to a standard pattern </div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In terms of code implementation, we can directly call the method `standardize` to complete the standarization process. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Standarization\n",
    "mc.standardize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Simplification and optimization\n",
    "\n",
    "Once a standard pattern is obtained, one option is to directly pass it to the MBQC simulation module and run the simulation. However, a better job can be done before the simulation. Just like the quantum circuit optimization which aims to find a simpler but equivalent representation of the circuit, we can also find a refined pattern based on the standard one. Such refinement can be done in two approaches: removing the measurement dependency as much as possible and reordering the measurement commands. Both approaches aim to reduce the number of effective qubits involved in the actual simulation.\n",
    "\n",
    "Due to the above two considerations, we use a **signal shifting** operation to simplify the measurement dependencies and use a **row-major order optimization algorithm** to optimize the order of measurement commands."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Signal shifting**\n",
    "\n",
    "The operation of signal shifting aims to simplify dependency by pulling out a particular type of dependency from the measurement command and compensating it with a \"signal\" command [7]. In terms of code implementation, we can directly call the method `shift_signals` to realize this."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Signal shifting\n",
    "mc.shift_signals()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Row-major order optimization algorithm**\n",
    "\n",
    "The row-major order optimization algorithm is a new algorithm we propose. The intention is to measure vertices with row-major order. Once all vertices in a row are measured, we can completely remove this row, thereby reducing the number of effective vertices involved in subsequent operations. Intuitively speaking, this method makes quantum gates and measurements executed by rows in some sense. Numerical experiments show that this optimization technique provides a significant improvement for the simulation of quantum shallow circuits (see below).\n",
    "\n",
    "In terms of code implementation, we can directly call `optimize_by_row` to implement the row-major optimization algorithm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optimize the measurement order\n",
    "mc.optimize_by_row()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we can call the method `get_pattern` to get the optimized pattern."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the Pattern\n",
    "pattern = mc.get_pattern()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Simulation\n",
    "\n",
    "Once we have the optimized pattern, we can call the method `set_pattern` in `MBQC` to pass it to the simulation module and call `run_pattern` to start the simulation process."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import required modules\n",
    "from paddle_quantum.mbqc.simulator import MBQC\n",
    "from paddle_quantum.mbqc.qobject import State\n",
    "from paddle_quantum.mbqc.utils import zero_state, kron, div_str_to_float\n",
    "\n",
    "# Instantiate MBQC\n",
    "mbqc = MBQC()\n",
    "\n",
    "# Input the pattern\n",
    "mbqc.set_pattern(pattern)\n",
    "\n",
    "# Input the initial quantum state. Here we choose |0> state to consist with the circuit model\n",
    "input_vector = kron([zero_state() for _ in range(qubit_number)])\n",
    "input_system = [0,1]\n",
    "input_state = State(input_vector, input_system)\n",
    "\n",
    "mbqc.set_input_state(input_state)\n",
    "\n",
    "# Run pattern\n",
    "mbqc.run_pattern()\n",
    "\n",
    "# Obtain quantum output\n",
    "quantum_output = mbqc.get_quantum_output()\n",
    "print(\"The quantum output state is：\", quantum_output)\n",
    "\n",
    "# Obtain classcial output\n",
    "classical_output = mbqc.get_classical_output()\n",
    "print(\"The classical output is：\", classical_output)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At this point, we have achieved the entire process of circuit simulation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Function \"simulate_by_mbqc\"\n",
    "\n",
    "For convenience, we provide a function `simulate_by_mbqc` to pack the whole process of quantum circuit simulation. We can construct a circuit from ``Circuit`` first and then call `simulate_by_mbqc` to run the simulation process. This function translates the constructed circuit to its MBQC equivalent, runs the simulation, and finally returns the classical outcomes or quantum state vector equivalent to the quantum circuit model. An example is given as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import required modules\n",
    "from numpy import random, pi\n",
    "from paddle import to_tensor\n",
    "\n",
    "# Import utils modules\n",
    "from paddle_quantum.mbqc.utils import random_state_vector\n",
    "# Import Circuit modules\n",
    "from paddle_quantum.mbqc.qobject import Circuit\n",
    "# Import simulation module\n",
    "from paddle_quantum.mbqc.simulator import simulate_by_mbqc\n",
    "\n",
    "# Set rotation angle theta \n",
    "theta = random.rand(4) * 2 * pi \n",
    "    \n",
    "# Transform 'Numpy array' to 'Tensor' in Paddle\n",
    "theta = to_tensor(theta)\n",
    "\n",
    "# Instaniate a quantum circuit\n",
    "qubit_number = 2\n",
    "cir = Circuit(qubit_number)\n",
    "\n",
    "# Add Ry gate\n",
    "cir.ry(theta[0], 0)\n",
    "cir.ry(theta[1], 1)\n",
    "\n",
    "# Add CNOT gate\n",
    "cir.cnot([0, 1])\n",
    "\n",
    "# Add Ry gate\n",
    "cir.ry(theta[2], 0)\n",
    "cir.ry(theta[3], 1)\n",
    "\n",
    "# Input the measurement information\n",
    "# Measure all qubits by default\n",
    "cir.measure()\n",
    "\n",
    "# Construct the input state\n",
    "input_vector = random_state_vector(qubit_number)\n",
    "input_system = list(range(qubit_number))\n",
    "input_state = State(input_vector, input_system)\n",
    "\n",
    "\n",
    "# Call the function to simulate quantum circuit by MBQC\n",
    "classical_output, quantum_output = simulate_by_mbqc(cir, input_state)\n",
    "\n",
    "# Print the returned classical and quantum outputs\n",
    "print(\"Classical output is：\", classical_output)\n",
    "print(\"Quantum output is：\", quantum_output)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Examples\n",
    "\n",
    "Due to the incapability of error correction in near-term quantum computers, parallelism and circuit depth become crucial factors in designing quantum algorithms. We hope to design algorithms with high-performance parallelism and low circuit depth, such that quantum computers can accomplish the algorithm execution as soon as possible, to reduce the influence of decoherence to the result's accuracy. Thereby, quantum algorithms using shallow circuits will play an important role in the near-term. \n",
    "\n",
    "In the following, we use two classes of quantum shallow circuits to demonstrate the superiority of our simulation scheme.\n",
    "\n",
    "### Google Random Circuit\n",
    "In 2017, Google proposed a series of random quantum circuits (GRCS). Due to the hardness of simulation, GRCS is frequently used as benchmark to test the performance of classical simulators [9].\n",
    "\n",
    "To demonstrate the efficiency of our simulation scheme, we select part of the shallow circuits (in particular, circuits with CZ gates of **depth 10** ) from the [GRCS library](https://github.com/sboixo/GRCS). The specific circuits selected are as follows:\n",
    "\n",
    "|Index|File Name|Qubit Number|\\||Index|File Name|Qubit Number|\\||Index|File Name|Qubit Number|\\||Index|File Name|Qubit Number|\\||Index|File Name|Qubit Number|\n",
    "| :---: | :---: | :---: | :---:| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |:---: |:---: |:---: |\n",
    "|1|inst_5x5_10_0.txt|25|**\\|** | 11|inst_5x6_10_0.txt|30|**\\|**|21|inst_6x6_10_0.txt|36|**\\|**|31|inst_6x7_10_0.txt|42|**\\|**|41|inst_7x7_10_0.txt|49|\n",
    "|2|inst_5x5_10_1.txt|25|**\\|**| 12|inst_5x6_10_1.txt|30|**\\|**|22|inst_6x6_10_1.txt|36|**\\|**|32|inst_6x7_10_1.txt|42|**\\|**|42|inst_7x7_10_1.txt|49|\n",
    "|3|inst_5x5_10_2.txt|25|**\\|**| 13|inst_5x6_10_2.txt|30|**\\|**|23|inst_6x6_10_2.txt|36|**\\|**|33|inst_6x7_10_2.txt|42|**\\|**|43|inst_7x7_10_2.txt|49|\n",
    "|4|inst_5x5_10_3.txt|25|**\\|**| 14|inst_5x6_10_3.txt|30|**\\|**|24|inst_6x6_10_3.txt|36|**\\|**|34|inst_6x7_10_3.txt|42|**\\|**|44|inst_7x7_10_3.txt|49|\n",
    "|5|inst_5x5_10_4.txt|25|**\\|**| 15|inst_5x6_10_4.txt|30|**\\|**|25|inst_6x6_10_4.txt|36|**\\|**|35|inst_6x7_10_4.txt|42|**\\|**|45|inst_7x7_10_4.txt|49|\n",
    "|6|inst_5x5_10_5.txt|25|**\\|**| 16|inst_5x6_10_5.txt|30|**\\|**|26|inst_6x6_10_5.txt|36|**\\|**|36|inst_6x7_10_5.txt|42|**\\|**|46|inst_7x7_10_5.txt|49|\n",
    "|7|inst_5x5_10_6.txt|25|**\\|**| 17|inst_5x6_10_6.txt|30|**\\|**|27|inst_6x6_10_6.txt|36|**\\|**|37|inst_6x7_10_6.txt|42|**\\|**|47|inst_7x7_10_6.txt|49|\n",
    "|8|inst_5x5_10_7.txt|25|**\\|**| 18|inst_5x6_10_7.txt|30|**\\|**|28|inst_6x6_10_7.txt|36|**\\|**|38|inst_6x7_10_7.txt|42|**\\|**|48|inst_7x7_10_7.txt|49|\n",
    "|9|inst_5x5_10_8.txt|25|**\\|**| 19|inst_5x6_10_8.txt|30|**\\|**|29|inst_6x6_10_8.txt|36|**\\|**|39|inst_6x7_10_8.txt|42|**\\|**|49|inst_7x7_10_8.txt|49|\n",
    "|10|inst_5x5_10_9.txt|25|**\\|**| 20|inst_5x6_10_9.txt|30|**\\|**|30|inst_6x6_10_9.txt|36|**\\|**|40|inst_6x7_10_9.txt|42|**\\|**|50|inst_7x7_10_9.txt|49|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We compare the running time between our simulation scheme and two other simulators (`statevector` and `matrix_product_state`) in Qiskit. We choose a shorter time from `statevector` and `matrix_product_state` as the running time of the Qiskit simulator. All the numerical experiments are conducted on a standard laptop with 16G RAM and Intel Core i7 10TH GEN CPU. The time comparison is shown in Figure 4. It is clear that our new simulation scheme provides a significant improvement over the Qiskit simulators for simulating shallow circuits.\n",
    "\n",
    "![GRCS plot](./figures/mbqc-fig-GRCS_plot.jpg)\n",
    "<div style=\"text-align:center\">Figure 4: Time comparison between Qiskit and our MBQC simulation scheme for different instances</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusion\n",
    "\n",
    "MBQC model provides a different technical route to realize universal quantum computation, in parallel with the quantum circuit model. By going from circuits to their MBQC equivalents, this tutorial provides a new scheme to speed up quantum circuit simulation. The improvement of our simulation scheme is evident for shallow circuits. We expect that this new idea will bring further advantages in applications of quantum machine learning and quantum neural networks.\n",
    "\n",
    "Although we adopt the state vector for underlying simulation in the current MBQC package, the idea of quantum circuit simulation by MBQC is not limited to any data structure. \n",
    "\n",
    "In terms of quantum circuit simulation and MBQC based algorithms, there are still lots of unknowns to explore. Welcome to join us and discover the infinite possibilities of MBQC together!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## References\n",
    "\n",
    "[1] Preskill, John. \"Quantum computing and the entanglement frontier.\" [arXiv preprint arXiv:1203.5813 (2012).](https://arxiv.org/abs/1203.5813)\n",
    "\n",
    "[2] Preskill, John. \"Quantum computing in the NISQ era and beyond.\" [Quantum 2 (2018): 79.](https://quantum-journal.org/papers/q-2018-08-06-79/)\n",
    "\n",
    "[3] Robert Raussendorf, et al. \"A one-way quantum computer.\" [Physical Review Letters 86.22 (2001): 5188.](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.86.5188)\n",
    "\n",
    "[4] Raussendorf, Robert, and Hans J. Briegel. \"Computational model underlying the one-way quantum computer.\" [Quantum Information & Computation 2.6 (2002): 443-486.](https://dl.acm.org/doi/abs/10.5555/2011492.2011495)\n",
    "\n",
    "[5] Robert Raussendorf, et al. \"Measurement-based quantum computation on cluster states.\" [Physical Review A 68.2 (2003): 022312.](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.68.022312)\n",
    "\n",
    "[6] Briegel, Hans J., et al. \"Measurement-based quantum computation.\" [Nature Physics 5.1 (2009): 19-26.](https://www.nature.com/articles/nphys1157)\n",
    "\n",
    "[7] Danos, Vincent, et al. \"The measurement calculus.\" [Journal of the ACM (JACM) 54.2 (2007): 8-es.](https://dl.acm.org/doi/abs/10.1145/1219092.1219096)\n",
    "\n",
    "[8] Broadbent, Anne, and Elham Kashefi. \"Parallelizing quantum circuits.\" [Theoretical computer science 410.26 (2009): 2489-2510.](https://arxiv.org/abs/0704.1736)\n",
    "\n",
    "[9] Boixo, Sergio, et al. \"Characterizing quantum supremacy in near-term devices.\" [Nature Physics 14.6 (2018): 595-600.](https://www.nature.com/articles/s41567-018-0124-x)"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "73e152e9b81fe728e387c249fa9090f02d423820fe8ab6018c11ce80df71d553"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "toc-autonumbering": false,
  "toc-showcode": false,
  "toc-showmarkdowntxt": false,
  "toc-showtags": false,
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
